﻿using System.Linq;
using System.Web.Mvc;
using System.Collections.Generic;
using Kelper.ViewModels;
using Kelper.Domain.Models;
using Kelper.Domain.Data.Abstract;
using Kelper.Infrastructure.Filters;
using Kelper.Infrastructure.Abstract;

namespace Kelper.Controllers
{
    [ValidateInput(false)]
    public class UserController : BaseController
    {
        private IRecipeRepository recipes;
        private IUserRepository users;              

        public UserController(IUserRepository userRepo, IRecipeRepository recipeRepo)
            : this(userRepo, recipeRepo, null) { }

        public UserController(IUserRepository userRepo, IRecipeRepository recipeRepo, IAccountManager manager)
            : base(manager)
        {
            users = userRepo;        
            recipes = recipeRepo;
        }

        [Login]
        public ViewResult Index(int page = 1)
        {
            IEnumerable<Recipe> items = recipes.Recipes
                .OrderByDescending(r => r.Created)
                .Where(r => r.Author.Username == accounts.CurrentUser);
            IEnumerable<Recipe> result = Paginate(items, page);

            return View(new UserViewModel
            {
                Recipes = result, 
                CurrentPage = page, ItemsPerPage = PageSize,
                TotalItems = items.Count()
            });
        }

        public RedirectToRouteResult Logout()
        {
            accounts.Logout();
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Login(string target = null)
        {
            if (accounts.IsLoggedIn())
                return RedirectToAction("Index", "Home");

            ViewBag.Target = target;
            return View(new UserViewModel());
        }

        [HttpPost]
        public ActionResult Login(UserViewModel credentials, string target = null)
        {
            ViewBag.Target = target;
            if (!ModelState.IsValid)
                return View(credentials);

            User user = users.Users.FirstOrDefault(u => u.Username == credentials.Username);
            if (user == null || !user.PasswordEquals(credentials.Password))
            {
                ModelState.AddModelError("", "Incorrect username or password");
                return View(credentials);
            }

            accounts.Login(user.Username);
            if (target == null)
                return RedirectToAction("Index", "Home");
            else
                return Redirect(target);
        }

        public ActionResult Register()
        {
            if (accounts.IsLoggedIn())
                return RedirectToAction("Index", "Home");

            return View(new User());
        }

        [HttpPost]
        public ActionResult Register(User user)
        {
            if (!ModelState.IsValid)
                return View(user);

            if (!users.Register(user))
            {
                ModelState.AddModelError("", "Username or email address already registered");
                return View(user);
            }

            accounts.Login(user.Username);
            TempData["message"] = "Thank you for registering!";
            return RedirectToAction("Index", "Home");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Unregister()
        {
            string user = accounts.CurrentUser;
            if (user != null)
            {
                users.Unregister(user);
                accounts.Logout();
                TempData["message"] = "Unregistered!";
            }
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Visit(string id)
        {
            User user = users.Users.FirstOrDefault(u => u.Username == id);
            if (user == null)
                return HttpNotFound();

            return View(user);
        }
    }
}
